package com.example.dict.utils.util;

import java.util.BitSet;

/**
 * @author wey
 *
 * 哈希表存储单词信息
 * */
public class HashSet {


    /**
     *
     * 默认哈希数组大小
     * */
    private static final int defaultSize = Integer.MAX_VALUE;


    /**
     *
     * 哈希数组
     * */
    private static final BitSet bitSet = new BitSet(defaultSize);


    /**
     * 哈希函数种子
     * */
    private static final int[] SEED = new int[]{7, 19, 43};


    /**
     *
     * */
    private static final InnerHashSet[] innerHashSets = new InnerHashSet[SEED.length];



    /**
     * 初始化
     * */
    public HashSet() {
        for (int i = 0; i < SEED.length; i++) {
            innerHashSets[i] = new InnerHashSet(SEED[i]);
        }
    }

    /**
     * 判断key是否在哈希数组中
     * @param key 查询的值
     * @return 存在返回true 否则返回false
     * */
    public boolean contains(String key) {
        if (null == key || key.isEmpty()) {
            return false;
        }

        boolean ans = true;
        for (int i = 0; i < SEED.length; i++) {
            ans = ans && bitSet.get(innerHashSets[i].hash(key));
        }

        return ans;
    }


    /**
     * @param key 添加
     * @return 添加成功返回true 否则false
     * */
    public boolean add(String key) {
        if (null == key || key.isEmpty()) {
            return false;
        }

        for (int i = 0; i < SEED.length; i++) {
            if (bitSet.get(innerHashSets[i].hash(key))) {
                return false;
            } else {
                bitSet.set(innerHashSets[i].hash(key));
            }
        }
        return true;
    }


        /**
         * 根据不同的种子 做不同的hash算法
         * 使用不同的哈希值
         */
        private record InnerHashSet(int seed) {

        public int hash(String value) {
                int res = 0;
                char[] values = value.toCharArray();
                for (char v : values) {
                    res = res * seed + v;
                }

                return res & (defaultSize - 1);
            }
        }

}
